package com.chebaohui.iqs.service.impl.deal.libao.profess;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.fastjson.JSONObject;
import com.chebaohui.iqs.config.CompanyValue;
import com.chebaohui.iqs.entity.base.CarOrder;
import com.chebaohui.iqs.entity.db.DbParam;
import com.chebaohui.iqs.entity.req.CarPays;
import com.chebaohui.iqs.entity.res.CompanyCarPermit;
import com.chebaohui.iqs.service.impl.deal.libao.sdk.LibaoRequest;
import com.chebaohui.iqs.service.impl.deal.libao.util.LibaoConfig;
import com.chebaohui.iqs.service.impl.deal.libao.util.PublicParam;
import com.chebaohui.iqs.service.impl.deal.util.StringUtil;

/**
 * 利宝直连接口支付登记
 * 
 * @author regas_xie
 *
 */
public class LbPayRegister {
	private DbParam dbParam;
	private CarPays param;
	/**
	 * log:日志输出
	 */
	private Log log = LogFactory.getLog(LbPayRegister.class);

	public LbPayRegister(CarPays param) {
		this.param = param;
		this.dbParam = new DbParam();
	}

	public DbParam getDbParam() {
		return dbParam;
	}

	/**
	 * 支付登记
	 * 
	 * @param param
	 * @return
	 */
	public CompanyCarPermit register() throws Exception {
		Map<String, String> map = PublicParam.getParam(param.getCarOrder().getOrederNo());
		log.info(map.get("flowId") + ",进入利宝支付登记开始...");

		String documentNo = "";
		if (StringUtil.isNulls(param.getCarOrder().getBusInsuranceNo()))
			documentNo = param.getCarOrder().getTraInsuranceNo();
		else
			documentNo = param.getCarOrder().getBusInsuranceNo();

		// 获取加密字段
		Map<String, String> md5 = md5Map(map);
		md5.put("documentNo", documentNo);
		md5.put("payment", "1");
		// 接口请求参数
		JSONObject json = PublicParam.getParam(map);

		json.put("pdk", PublicParam.getPdk(md5));
		json.put("documentNo", documentNo);

		json.put("callBackUrl", CompanyValue.PATH + "/price/libao/pay");// 支付后回调后台地址
		json.put("deviceType", "wap");// 设备类型
		json.put("redirectUrl", CompanyValue.PATH + "/price/libao/back");// 支付后前台通知地址

		String str = LibaoRequest.postForm(
				LibaoConfig.libao_url + "/payment/index" + "?access_token=" + map.get("access_token"),
				LibaoRequest.getFormBody(json));

		if (StringUtil.isNulls(str)) {
			log.error(map.get("flowId") + ",利宝支付登记请求json:" + json);
			log.error(map.get("flowId") + ",进入利宝支付登记(利宝请求失败)...");
			throw new Exception("利宝--请求失败(请求返回null)");
		}

		log.info(map.get("flowId") + ",支付页面:" + str);

		JSONObject pays = jieXiJson(str);
		pays.put("libaoFlowId", map.get("flowId"));
		pays.put("timeLongTo", new Date().getTime());

		try {
			dbParam.setcType("insurance");
			dbParam.setNumType("libao-pay");
			dbParam.setReserve(map.get("flowId"));
			dbParam.setReserve(new Date().getTime() + "");
			dbParam.setDatas(pays.toJSONString());
		} catch (Exception e) {
			log.error(map.get("flowId") + ",利宝支付登记加入mysql缓存出现异常:" + e);
			throw new Exception("利宝支付缓存异常:" + e.getMessage());
		}

		CompanyCarPermit result = new CompanyCarPermit();
		result.setCompanyCode(param.getCompanyCode());
		CarOrder order = param.getCarOrder();
		order.setPayUrl(CompanyValue.PATH + "/price/libao/val?" + "libaoFlowId=" + map.get("flowId"));
		result.setCarOrder(order);

		return result;
	}

	/**
	 * 支付登记接口加密字段获取
	 * 
	 * @param map
	 * @return
	 */
	private Map<String, String> md5Map(Map<String, String> map) {
		Map<String, String> md5 = new HashMap<String, String>();
		md5.put("partnerAccountCode", map.get("partnerAccountCode"));
		md5.put("agreementNo", map.get("agreementNo"));
		md5.put("recordCode", map.get("recordCode"));
		md5.put("flowId", map.get("flowId"));
		return md5;
	}

	/**
	 * 提取html文本中input标签组成json
	 * 
	 * @param html
	 * @return
	 */
	public JSONObject jieXiJson(String html) {
		if (StringUtil.isNulls(html))
			return null;
		try {
			Document doc = Jsoup.parse(html);
			Elements ele = doc.getElementsByTag("input");
			JSONObject obj = new JSONObject();
			for (Element e : ele) {
				obj.put(e.attr("name").trim(), getValue(e.val()));
			}
			Element form = doc.getElementsByTag("form").get(0);
			obj.put("formAction", form.attr("action").trim());
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private String getValue(String val) {
		if (StringUtil.isNulls(val))
			return "";
		else
			return val;
	}
}
